#include "common.h"
PRIVATE U4B      cgabyteposition=0;
PUBLIC VOID CGA2580ShowAttributeCharacter(U1B attribute,CHAR character)
{
   if(cgabyteposition>=CGAMAXBYTES)
       cgabyteposition=0;
   if(character==0x0A)
   {
      cgabyteposition=(cgabyteposition/CGABYTESNUMBERPERROW + 1)*CGABYTESNUMBERPERROW;
      return;
   }
      __asm__ __volatile__(
           "movb %%bl,%%ah\n\t"
           "movl $0,%%ebx\n\t"
           "movw %%cx,%%bx\n\t"
           "movl %%ebx,%%ecx\n\t"
           "movw %%ax,%%gs:(%%ecx)\n\t"
           :
           :"a"(character),"b"(attribute),"c"(cgabyteposition)
           :"memory");
    cgabyteposition+=2;
}




PRIVATE CHAR buffer[1024];  /*This variable is just effective in this file.*/
PRIVATE S4B CGA2580ShowAttributeString(PCHAR string,U4B number)
{
   U4B  count=0;
    for(;count<number;count+=2)
    {
       CGA2580ShowAttributeCharacter(string[count],string[count+1]);
    }
   return number;
}
PUBLIC S4B Print(PCCHAR format,...)
{
    MemorySet((PVOID)buffer,1024,0);
    VA_LIST  args;
    Va_Start(args,format);
    U4B     color=0x0F;
    PCCHAR  fmt=format;
    U4B     bufferposition=0;
    U4B     width=0;
    while(*fmt != '\0')
    {
       if(*fmt != '%')
       {
          buffer[bufferposition]   = GetLastByte(color);
          buffer[bufferposition+1] = *fmt;
          bufferposition+=2;
          fmt++;
          continue;
       }
       else
          fmt++;
       if(*fmt=='#')
       {
          fmt ++ ;
          fmt += UHexStringToNumber(fmt,2,&color); 
       } 
       fmt+=UDecStringToNumber(fmt,2,&width);
       switch(*fmt)
       {
          case 'X':
          {
             CHAR localbuffer[8];
             S4B  j = U4BToBigHexString((Va_Arg(args,U4B)),localbuffer);
             S4B  i=0;
             for(;i<j;i++)
             {
                buffer[bufferposition]   = GetLastByte(color);
                buffer[bufferposition+1] = localbuffer[i];
                bufferposition+=2;
             }
             if(width>j)
             {
                for(i=0;i<width-j;i++)
                {
                   buffer[bufferposition]   = GetLastByte(color);
                   buffer[bufferposition+1] = 0x20;
                   bufferposition+=2;
                }
             }
             fmt++;
             break;
          }
          case 's':
          {
              PCHAR string=Va_Arg(args,PCHAR);
              U4B i;
              for(i=0;string[i]!='\0';i++)
              {
                   buffer[bufferposition]   = GetLastByte(color);
                   buffer[bufferposition+1] = string[i];
                   bufferposition+=2;
              }
              fmt++;
              break;
          }
       }
      color=0x0F;
      width=0;
    }    
   Va_End(args);
   return CGA2580ShowAttributeString(buffer,bufferposition);
}

PUBLIC S4B SetCursorXY(U1B x,U1B y)
{
    if(x>=CGAMAXCOLUMNNUMBER) x=CGAMAXCOLUMNNUMBER-1;
    if(y>=CGAMAXROWNUMBER) y=CGAMAXROWNUMBER-1;
    cgabyteposition=y*CGABYTESNUMBERPERROW+x*CGABYTESPERCHARACTER;
    return ARTIST_ERROR_OK;
}
PUBLIC S4B ClearScreen()
{
    U2B i=0;
    for(i=0;i<CGAMAXCHARACTERS;i++)
       CGA2580ShowAttributeCharacter(0x00,0);
    SetCursorXY(0,0);
    return ARTIST_ERROR_OK;
}

PUBLIC S4B PrintLimitedString(PCCHAR string,U4B number)
{
    U4B i;
    CHAR s[2];
    s[1]='\0';
    for(i=0;i<number;i++)
    {
       s[0]=string[i];
       Print("%s",s);
    }
   
    return ARTIST_ERROR_OK;
}




























